﻿using System;
using System.Collections.Generic;
using Autofac;

namespace zDit.Core
{
    /// <summary>
    /// 通过此转换器获得的同一类型的对象均是同一实例，由于使用的是同一生命周期
    /// </summary>
    public class AutofacGenericDependencyResolver
    {
        private readonly ILifetimeScope _container;
        private readonly Action<ContainerBuilder> _configurationAction;
        private ILifetimeScopeProvider _lifetimeScopeProvider;
        public static AutofacGenericDependencyResolver Current
        {
            get; 
            set;
        }
        public ILifetimeScope RequestLifetimeScope
        {
            get
            {
                Action<ContainerBuilder> configurationAction = delegate(ContainerBuilder builder)
                {
                    if (this._configurationAction != null)
                    {
                        this._configurationAction(builder);
                    }
                    builder.RegisterInstance(this).As<AutofacGenericDependencyResolver>();
                };
                if (this._lifetimeScopeProvider == null)
                {
                    this._lifetimeScopeProvider = new AutofacGenericLifetimeScopeProvider(this._container);
                }
                return this._lifetimeScopeProvider.GetLifetimeScope(configurationAction);
            }
        }
        public ILifetimeScope ApplicationContainer
        {
            get
            {
                return this._container;
            }
        }
        public AutofacGenericDependencyResolver(ILifetimeScope container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            this._container = container;
        }
        public AutofacGenericDependencyResolver(ILifetimeScope container, Action<ContainerBuilder> configurationAction)
            : this(container)
        {
            if (configurationAction == null)
            {
                throw new ArgumentNullException("configurationAction");
            }
            this._configurationAction = configurationAction;
        }
        public AutofacGenericDependencyResolver(ILifetimeScope container, ILifetimeScopeProvider lifetimeScopeProvider)
            : this(container)
        {
            if (lifetimeScopeProvider == null)
            {
                throw new ArgumentNullException("lifetimeScopeProvider");
            }
            this._lifetimeScopeProvider = lifetimeScopeProvider;
        }
        public AutofacGenericDependencyResolver(ILifetimeScope container, ILifetimeScopeProvider lifetimeScopeProvider, Action<ContainerBuilder> configurationAction)
            : this(container, lifetimeScopeProvider)
        {
            if (configurationAction == null)
            {
                throw new ArgumentNullException("configurationAction");
            }
            this._configurationAction = configurationAction;
        }

        public T Resolve<T>(string key = "") where T : class
        {
            if (string.IsNullOrEmpty(key))
            {
                return RequestLifetimeScope.Resolve<T>();
            }
            return RequestLifetimeScope.ResolveKeyed<T>(key);
        }

        public object GetService(Type serviceType)
        {
            return this.RequestLifetimeScope.ResolveOptional(serviceType);
        }
        public IEnumerable<object> GetServices(Type serviceType)
        {
            Type serviceType2 = typeof(IEnumerable<>).MakeGenericType(new Type[]
			{
				serviceType
			});
            object obj = this.RequestLifetimeScope.Resolve(serviceType2);
            return (IEnumerable<object>)obj;
        }
    }
}
